/*/////////////////////////////////////////////////////////////////////////////////
/// An
///    ___   ____ ___ _____ ___  ____
///   / _ \ / ___|_ _|_   _/ _ \|  _ \
///  | | | | |  _ | |  | || | | | |_) |
///  | |_| | |_| || |  | || |_| |  _ <
///   \___/ \____|___| |_| \___/|_| \_\
///                              File
///
/// Copyright (c) 2008-2009 Ismail TARIM <ismail@royalspor.com> and the Ogitor Team
//
//This program is free software; you can redistribute it and/or modify it under
//the terms of the GNU Lesser General Public License as published by the Free Software
//Foundation; either version 2 of the License, or (at your option) any later
//version.
//
//This program is distributed in the hope that it will be useful, but WITHOUT
//ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
//FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License along with
//this program; if not, write to the Free Software Foundation, Inc., 59 Temple
//Place - Suite 330, Boston, MA 02111-1307, USA, or go to
//http://www.gnu.org/copyleft/lesser.txt.
////////////////////////////////////////////////////////////////////////////////*/

#pragma once

namespace Ogitors
{
    //! Sub-mesh data class
    /*!  
        A class that keeps track of single sub-mesh
    */
    struct SubMeshData
    {
        Ogre::String Material;
        bool         Visible;
    };

    //! Entity editor class
    /*!  
        Entity editor class that assists in editing Entity(ies)
    */
    class OgitorExport CEntityEditor : public CNodeEditor
    {
        friend class CEntityEditorFactory;
    public:
        /** @copydoc CBaseEditor::getFactory() */
		static CBaseEditorFactory *getFactory();
		/** @copydoc CBaseEditor::getFactoryDynamic() */
		virtual CBaseEditorFactory *getFactoryDynamic();
        /**
        * Sets mesh file name
        * @param value mesh file name
        * @param display flag signifying whether or not to update mesh file name field in treeview
        */
        void         setMeshFile(const Ogre::String& value, bool display);
        /**
        * Fetches mesh file name
        * @return mesh file name
        */
        Ogre::String getMeshFile();
        /**
        * Sets casting shadows flag; if true, entities will be casting shadows
        * @param value casting shadows flag
        * @param display flag signifying whether or not to update casting shadows field in treeview
        */
        void         setCastShadows(const bool& value, bool display);
        /**
        * Fetches casting shadows flag
        * @return casting shadows flag
        */
        bool         getCastShadows();
        /**
        * Sets sub-mesh data
        * @param value sub-mesh data
        * @param display flag signifying whether or not to update sub-mesh field in treeview
        */
        void         setSubMesh(SubMeshData *value, int index, bool display);
        /**
        * Fetches sub-mesh data
        * @return sub-mesh data
        */
        SubMeshData *getSubMesh(int index);
        /** @copydoc CBaseEditor::load() */
        virtual bool load();
        /** @copydoc CBaseEditor::unLoad() */
        virtual bool unLoad();
        /** @copydoc CBaseEditor::processParameters(Ogre::NameValuePairList &) */
        virtual void processParameters(Ogre::NameValuePairList &params);

        /** @copydoc CBaseEditor::onDropMaterial(Ogre::Vector3, const Ogre::String&) */
        virtual void onDropMaterial(Ogre::Vector3 position, const Ogre::String& materialname);
        /** @copydoc CBaseEditor::getObjectProperties(Ogre::NameValuePairList &) */
        virtual void getObjectProperties(Ogre::NameValuePairList &retList);
        /** @copydoc CBaseEditor::setupPropertiesWnd(bool) */
        virtual bool setupPropertiesWnd(bool present);
        /** @copydoc CBaseEditor::showBoundingBox(bool) */
        virtual void showBoundingBox(bool bShow);
        /** @copydoc CBaseEditor::getAABB() */
        virtual Ogre::AxisAlignedBox getAABB() {if(m_EntityHandle) return m_EntityHandle->getBoundingBox();else return Ogre::AxisAlignedBox::BOX_NULL;};
        /** @copydoc CBaseEditor::setupPropertiesWnd(Ogre::NameValuePairList &) */
        virtual void            restore(Ogre::NameValuePairList &retList);
        /** @copydoc CBaseEditor::getHandle() */
        inline virtual void    *getHandle() {return static_cast<void*>(m_EntityHandle);};

    protected:
        Ogre::Entity            *m_EntityHandle;            /** Actual mesh handle */
        Ogre::String             m_MeshFile;                /** Mesh file name */
        bool                     m_CastShadows;             /** Casting shadows flag */
        std::vector<SubMeshData> m_SubMeshes;               /** A list of entity sub-meshes */

        /** 
        * Constructor
        */
        CEntityEditor();
        /** 
        * Destructor
        */
        virtual     ~CEntityEditor() {};
        /** @copydoc CBaseEditor::handleCustomFunction(int,Ogre::String) */
        virtual bool handleCustomFunction(int BIND_ID,Ogre::String val);
    };

    //! Entity editor factory class
    /*!  
        A class that instantiates Entity editor and tracks it thereafter
    */
    class OgitorExport CEntityEditorFactory: public CBaseEditorFactory
    {
    public:
        /** @copydoc CBaseEditorFactory::CBaseEditorFactory() */
        CEntityEditorFactory();
        /** @copydoc CBaseEditorFactory::~CBaseEditorFactory() */
        virtual ~CEntityEditorFactory() {};
        /** @copydoc CBaseEditorFactory::Init() */
        virtual void Init();
        /** @copydoc CBaseEditorFactory::CreateObject(CBaseEditor **, Ogre::NameValuePairList &) */
        virtual CBaseEditor *CreateObject(CBaseEditor **parent, Ogre::NameValuePairList &params);
    };

}
